home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Practical Algorithms for Image Analysis
/
Practical Algorithms for Image Analysis.iso
/
CH_4.4
/
XPM
/
PROC_POL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1999-09-11
|
8KB
|
280 lines
/*
* proc_pol.c
*
* Practical Algorithms for Image Analysis
*
* Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
*/
/*
* PROC(ess)_POLY(gon)
*
* polygon analysis:
* -----------------
* reconstruct polygon;
* determine area by pixel counting
* (and, in poly_moments(), by evaluating zero order moment);
*
* evaluate curvature energy based on Zahn chain code
*
* compute centroid, central moments and principal axes;
*
* find 2**n new vertices equi-spaced along contour
* determine radius vector relative to centroid; shift to zero mean;
* reconstruct angular bend function with respect to new set of vertices;
*
* compute power_spectrum and autocorrelation by AP FFT,
* for angular bend function (-->tan mode)
* for radial function (-->rad mode)
* for both (-->all)
* save to file (writes file for plotting by routine acmp);
*
* evaluate Zahn-Roskies Fourier descriptors
* write them to file (writes file for plotting by modeplt, multiplt);
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "ip.h"
#define ON_MODE 1
#define OFF_MODE 0
#define C_HEIGHT 10
#define C_WIDTH 10
#define C_COLOR 255
#define N2_LIMIT 64L
#define MAX_ZRFD 15L
#define N_MOMENTS 15
#define N_MODE_PARMS 2
#define ENLARGE 1.0
#define NOLOOP 0
#define MAX_ROW 2048
#define LOOP_COMPLETE 8.0
#define SQ2 1.414213562
#define ZERO 0.0
#define FABS(a) ((a) > ZERO ? (a) : - (a))
#define ON 1
#define OFF 0
#define SHIFT_CENTROID ON
#define SAVE_SHAPE OFF
#define EVAL_CURV_EN OFF /* evaluate curv. energy */
#define POLY_FIT ON /* invoke Wall-Danielsson fit */
#define DISPLAY_DATA
/* globals */
extern int page;
struct polygon *
select_poly (struct polygon *poly_head, Image * imgIO, int value)
{
struct polygon *current_poly;
int c;
int rad_mode = OFF, tan_mode = OFF;
float *s, *s_ap, *s_n2;
float *moments;
float *phi_k;
float *r_n2;
float *n2_phi_star;
float *acf, *p_spec;
int *mode_parms;
float *a_n = NULL, *b_n = NULL;
long nv, nv2;
int n_mom = N_MOMENTS;
int n_mp = N_MODE_PARMS;
unsigned int pixel_count;
double av_dirn = 0.0;
double c_len, ap_c_len, res_c_len;
double tot_phi;
double curv_en, e_bend;
double p2a_ratio;
struct Bdy bd, *bdp = &bd;
struct spoint *hullctr;
struct spoint cursor, *pc = &cursor;
struct spoint *v, *v_ap, *v_n2, *v_n2h;
struct spoint *pvc;
int hull_area;
char in_buf[IN_BUF_LEN];
/*
* cycle through list of boundary polygons
*/
printf ("...enter n to cycle, y to select poly...\n");
current_poly = poly_head;
for (;;) {
pc->x = current_poly->first_x;
pc->y = current_poly->first_y;
printf ("poly starting at (%d, %d) select?(y/n) ", pc->x, pc->y);
if ((c = readlin (in_buf)) == 'y')
break;
if ((current_poly = current_poly->next_poly) == NULL) {
printf ("At end of polygon list!! Return to first polygon? (y/n)");
if ((c = readlin (in_buf)) == 'n')
return (current_poly);
else
current_poly = poly_head;
}
}
nv = current_poly->poly_points;
nv2 = 2L;
while (nv2 < nv)
nv2 *= 2L;
if (nv2 >= N2_LIMIT)
nv2 = N2_LIMIT;
/*
* allocate memory
*/
if ((v = (struct spoint *) malloc ((nv + 1) * sizeof (struct spoint))) == NULL)
exitmess ("\n...mem allocation for v failed\n", 1);
if ((v_ap = (struct spoint *) malloc ((nv + 1) * sizeof (struct spoint))) == NULL)
exitmess ("\n...mem allocation for v_ap failed\n", 1);
if ((phi_k = (float *) malloc ((nv + 1) * sizeof (float))) == NULL)
exitmess ("\n...mem allocation for phi_k failed\n", 1);
if ((s = (float *) malloc ((nv + 1) * sizeof (float))) == NULL)
exitmess ("\n...mem allocation for s failed\n", 1);
if ((s_ap = (float *) malloc ((nv + 1) * sizeof (float))) == NULL)
exitmess ("\n...mem allocation for s_ap failed\n", 1);
if ((moments = (float *) malloc (n_mom * sizeof (float))) == NULL)
exitmess ("\n...mem allocation for moments failed\n", 1);
if ((v_n2 = (struct spoint *) malloc ((nv2 + 1) * sizeof (struct spoint))) == NULL)
exitmess ("\n...mem allocation for v_n2 failed\n", 1);
if ((v_n2h = (struct spoint *) malloc ((nv2 / 2) * sizeof (struct spoint))) == NULL)
exitmess ("\n...mem allocation for v_n2h failed\n", 1);
if ((r_n2 = (float *) malloc (nv2 * sizeof (float))) == NULL)
exitmess ("\n...mem allocation for r_n2 failed\n", 1);
if ((s_n2 = (float *) malloc ((nv2 + 1) * sizeof (float))) == NULL)
exitmess ("\n...mem allocation for s_n2 failed\n", 1);
if ((n2_phi_star = (float *) malloc (nv2 * sizeof (float))) == NULL)
exitmess ("\n...mem allocation for n2_phi_star failed\n", 1);
if ((acf = (float *) malloc (nv2 * sizeof (float))) == NULL)
exitmess ("\n...mem allocation for acf failed\n", 1);
if ((p_spec = (float *) malloc (nv2 * sizeof (float))) == NULL)
exitmess ("\n...mem allocation for p_spec failed\n", 1);
if ((mode_parms = (int *) malloc (n_mp * sizeof (int))) == NULL)
exitmess ("\n...mem allocation for mode_parms failed\n", 1);
/*
* evaluate arc_length and Zahn angular bend function
*/
c_len = arc_length (current_poly->d_l_ptr, s, nv);
tot_phi = angular_bend (current_poly->d_phi_ptr, phi_k, nv);
/*
* reconstruct polygon vertices
*/
pixel_count = reconstruct_poly (current_poly->d_phi_ptr,
current_poly->d_l_ptr, nv, v, pc,
current_poly->first_edge_out,
current_poly->total_delta_phi,
imgIO, value);
printf ("\n...object area (pixel count): %u", pixel_count);
/*
* evalate curvature energy from chain code representation
* note:
* to obtain robust estimates of curv_en, evaluation should really
* not be attempted before smoothing, e. g. via polygonal approx.,
* see below;
*/
if (EVAL_CURV_EN == ON) {
curv_en = curvature_energy (current_poly->d_phi_ptr,
current_poly->d_l_ptr, nv);
printf ("\n...chain-code derived curv. energy: %f\n", curv_en);
}
/*
* Wall-Danielsson polygonal approximation
*/
res_c_len = p2a_ratio = e_bend = -1.0;
if (POLY_FIT == ON) {
fill_bdy_structure (bdp, v, nv, tot_phi);
hullctr = poly_hull (bdp, v_ap, av_dirn, &hull_area, imgIO, GRAY);
printf ("\tlocation of convex hull center:");
printf (" (%3d,%3d)\n", hullctr->x, hullctr->y);
if ((nv - bdp->an) > 0) {
printf ("\n...approx poly size: %ld\n", nv = bdp->an);
v_ap = (struct spoint *) realloc (v_ap, (nv + 1) * sizeof (struct spoint));
nv2 = 2L;
while (nv2 < nv)
nv2 *= 2L;
}
/*
* evaluate polygon moments
*/
pvc = poly_moments (nv, v_ap, moments, imgIO, GRAY);
printf ("\n...centroid pos: (%3d, %3d)\n", pvc->x, pvc->y);
/*
* evaluate arc_length (partial sums of edge lengths) from set of
* vertices for approximated polygon;
*/
ap_c_len = vert_to_clen (v_ap, s_ap, nv);
/*
* resample new polygon at 2**n sites
*/
n2_vert (v_ap, s_ap, nv, v_n2, nv2, imgIO, 192);
}
else {
pvc = poly_moments (nv, v, moments, imgIO, GRAY);
n2_vert (v, s, nv, v_n2, nv2, imgIO, 192);
}
printf ("\n-->polygon analysis completed<--\n");
/*
* deallocate memory
*/
free (v);
free (v_ap);
free (v_n2);
free (v_n2h);
free (s);
free (s_ap);
free (s_n2);
free (phi_k);
free (moments);
free (r_n2);
free (n2_phi_star);
free (acf);
free (p_spec);
return (current_poly);
}